package com.wz.utils.concurrency.synchronizedlock;

import org.openjdk.jol.info.ClassLayout;

import lombok.extern.slf4j.Slf4j;
/**
 * 测试 偏向锁，轻量级锁，重量级锁标记变化
 * 关闭延迟开启偏向锁： -XX:BiasedLockingStartupDelay=0
 * 无锁 001
 * 偏向锁 101
 * 轻量级锁 00
 * 重量级锁 10
 */
@Slf4j
public class LockEscalationDemo2{

    public static void main(String[] args) throws InterruptedException {

        log.debug(ClassLayout.parseInstance(new Object()).toPrintable());
        //HotSpot 虚拟机在启动后有个 4s 的延迟才会对每个新建的对象开启偏向锁模式
        Thread.sleep(5000);
        Object obj = new Object();
        /**
         *  思考： 如果对象调用了hashCode,还会开启偏向锁模式吗
         *  可偏向状态调用hashcode()会变为无锁状态，并只能升级成轻量级锁
         **/
//        obj.hashCode();
        log.debug(ClassLayout.parseInstance(obj).toPrintable());

        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                log.debug(Thread.currentThread().getName() + "开始执行。。。\n"
                        + ClassLayout.parseInstance(obj).toPrintable());
                synchronized (obj) {

                    for (int i = 0; i < 100000; i++) {

                    }
                    log.debug(Thread.currentThread().getName() + "获取锁执行中。。。\n"
                            + ClassLayout.parseInstance(obj).toPrintable());
                }
                log.debug(Thread.currentThread().getName() + "释放锁。。。\n"
                        + ClassLayout.parseInstance(obj).toPrintable());
            }
        }, "thread1");
        thread.start();

        //控制线程竞争时机
//       Thread.sleep(1);

        Thread thread1 = new Thread(new Runnable() {
            @Override
            public void run() {
                log.debug(Thread.currentThread().getName() + "开始执行。。。\n"
                        + ClassLayout.parseInstance(obj).toPrintable());
                synchronized (obj) {
                    for (int i = 0; i < 100000; i++) {

                    }
                    log.debug(Thread.currentThread().getName() + "获取锁执行中。。。\n"
                            + ClassLayout.parseInstance(obj).toPrintable());
                }
                log.debug(Thread.currentThread().getName() + "释放锁。。。\n"
                        + ClassLayout.parseInstance(obj).toPrintable());
            }
        }, "thread2");
        thread1.start();

//        Thread.sleep(1);

        Thread thread3 = new Thread(new Runnable() {
            @Override
            public void run() {
                log.debug(Thread.currentThread().getName() + "开始执行。。。\n"
                        + ClassLayout.parseInstance(obj).toPrintable());
                synchronized (obj) {
                    for (int i = 0; i < 100000; i++) {

                    }

                    log.debug(Thread.currentThread().getName() + "获取锁执行中。。。\n"
                            + ClassLayout.parseInstance(obj).toPrintable());
                }

                log.debug(Thread.currentThread().getName() + "释放锁。。。\n"
                        + ClassLayout.parseInstance(obj).toPrintable());
            }
        }, "thread3");
        thread3.start();


        Thread.sleep(5000);
        log.debug(ClassLayout.parseInstance(obj).toPrintable());



    }
}
